# 智能新闻分类器
import re
import jieba
import logging

logger = logging.getLogger(__name__)

class NewsClassifier:
    """基于关键词的智能新闻分类器"""
    
    def __init__(self):
        # 定义各分类的关键词词典
        self.category_keywords = {
            # 政治时事类
            'politics': {
                'keywords': [
                    '政府', '国务院', '党委', '人大', '政协', '领导', '会议', '决议', '政策',
                    '法律', '法规', '立法', '执法', '司法', '条例', '规定', '办法',
                    '外交', '大使', '领事', '谈判', '协议', '条约', '合作', '峰会',
                    '选举', '投票', '候选人', '民主', '人权', '改革', '开放',
                    '反腐', '纪委', '监察', '违纪', '违法', '处分', '查处',
                    '维稳', '安全', '国防', '军事', '部队', '武装', '边防',
                    '统战', '民族', '宗教', '港澳', '台湾', '一带一路'
                ],
                'weight': 1.0
            },
            
            # 经济财经类
            'economics': {
                'keywords': [
                    '经济', 'GDP', '增长', '发展', '投资', '融资', '贷款', '债务',
                    '股票', '股市', '股价', '上市', 'IPO', '基金', '证券', '交易',
                    '银行', '央行', '利率', '汇率', '货币', '金融', '保险', '理财',
                    '房价', '房地产', '楼市', '土地', '拍卖', '开发商', '物业',
                    '税收', '税务', '关税', '进出口', '贸易', '外贸', '出口', '进口',
                    '企业', '公司', '集团', '公司', '营收', '利润', '亏损', '财报',
                    '市场', '消费', '零售', '电商', '购物', '商业', '商务',
                    '能源', '石油', '天然气', '煤炭', '电力', '新能源', '光伏',
                    '制造业', '工业', '农业', '服务业', '产业', '行业',
                    # 新增常用财经词汇
                    '万亿', '亿元', '千万', '百万', '跳水', '大涨', '爆发', '暴跌',
                    '行情', '板块', '龙头', '核心', '高估值', '低估值', '超跌',
                    '建仓', '清仓', '停牌', '复牌', '涨停', '跌停', '收盘',
                    '消息面', '政策面', '资金面', '技术面', '高开', '低开'
                ],
                'weight': 1.0
            },
            
            # 科技类
            'technology': {
                'keywords': [
                    '科技', '技术', '创新', '研发', 'AI', '人工智能', '机器学习', '深度学习',
                    '互联网', '网络', '在线', '数字化', '智能化', '自动化',
                    '手机', '电脑', '笔记本', '平板', '智能手机', '苹果', '华为', '小米',
                    '软件', '应用', 'APP', '程序', '系统', '操作系统', '数据库',
                    '芯片', '处理器', '半导体', '集成电路', '电子', '硬件',
                    '5G', '6G', '通信', '网络', '基站', '信号', '频谱',
                    '云计算', '大数据', '区块链', '虚拟现实', 'VR', 'AR', '元宇宙',
                    '电动车', '新能源车', '自动驾驶', '无人驾驶', '智能汽车',
                    '航空航天', '卫星', '火箭', '探测器', '空间站',
                    '生物科技', '基因', 'DNA', '医疗器械', '药物', '疫苗'
                ],
                'weight': 1.0
            },
            
            # 社会民生类
            'society': {
                'keywords': [
                    '社会', '民生', '社区', '居民', '市民', '群众', '百姓',
                    '教育', '学校', '学生', '老师', '考试', '招生', '毕业', '就业',
                    '医疗', '医院', '医生', '护士', '病人', '治疗', '手术', '药品',
                    '养老', '退休', '社保', '医保', '保障', '福利', '救助',
                    '交通', '道路', '地铁', '公交', '出行', '拥堵', '事故',
                    '环保', '环境', '污染', '治理', '绿化', '生态', '气候',
                    '住房', '租房', '安居', '保障房', '廉租房', '公租房',
                    '就业', '工作', '招聘', '失业', '创业', '职业', '岗位',
                    '文化', '艺术', '娱乐', '体育', '运动', '比赛', '赛事',
                    # 新增社会民生词汇
                    '志愿者', '公益', '慈善', '捐助', '爱心', '政务', '服务',
                    '老龄化', '人口', '生育', '无障碍', '残疾', '关爱',
                    '安全感', '幸福感', '获得感', '生活质量', '生活水平'
                ],
                'weight': 1.0
            },
            
            # 国际新闻类
            'international': {
                'keywords': [
                    '国际', '全球', '世界', '海外', '国外', '外国', '跨国',
                    '美国', '英国', '法国', '德国', '日本', '韩国', '俄罗斯', '印度',
                    '欧盟', '联合国', '北约', 'G7', 'G20', 'APEC', 'ASEAN',
                    '大使馆', '领事馆', '签证', '护照', '移民', '留学',
                    '战争', '冲突', '军事', '制裁', '谈判', '和平', '停火',
                    '疫情', '病毒', '传染病', '防疫', '封锁', 'WHO', '世卫',
                    '气候', '环境', '减排', '碳中和', '绿色', '可持续',
                    '贸易战', '关税', '制裁', '禁运', 'WTO', '世贸'
                ],
                'weight': 1.0
            },
            
            # 体育类
            'sports': {
                'keywords': [
                    '体育', '运动', '比赛', '赛事', '竞技', '冠军', '金牌', '奖牌',
                    '足球', '篮球', '排球', '乒乓球', '羽毛球', '网球', '高尔夫',
                    '游泳', '田径', '跑步', '马拉松', '健身', '瑜伽',
                    '奥运会', '世界杯', '亚运会', '全运会', 'NBA', 'CBA',
                    '运动员', '教练', '裁判', '球员', '队员', '选手',
                    '训练', '备战', '集训', '热身', '康复', '伤病',
                    '球队', '俱乐部', '联赛', '锦标赛', '邀请赛',
                    '成绩', '纪录', '破纪录', '夺冠', '获胜', '失利'
                ],
                'weight': 1.0
            },
            
            # 娱乐类
            'entertainment': {
                'keywords': [
                    '娱乐', '明星', '艺人', '演员', '歌手', '导演', '制片人',
                    '电影', '电视剧', '综艺', '节目', '演出', '音乐会', '演唱会',
                    '票房', '收视率', '播放量', '点击量', '热搜', '话题',
                    '颁奖', '获奖', '提名', '奖项', '红毯', '典礼',
                    '拍摄', '制作', '上映', '播出', '首映', '公映',
                    '粉丝', '观众', '影迷', '歌迷', '追星', '偶像',
                    '绯闻', '恋情', '结婚', '离婚', '出轨', '分手',
                    '网红', '直播', '短视频', '自媒体', '博主'
                ],
                'weight': 1.0
            },
            
            # 军事类
            'military': {
                'keywords': [
                    '军事', '军队', '部队', '军人', '士兵', '将军', '军官',
                    '国防', '安全', '防务', '战略', '战术', '作战', '演习',
                    '武器', '装备', '军备', '导弹', '飞机', '坦克', '军舰',
                    '核武器', '核试验', '军工', '军事工业', '装备制造',
                    '边防', '海防', '空防', '维和', '反恐', '巡逻',
                    '军区', '战区', '司令部', '参谋部', '后勤部',
                    '征兵', '退伍', '服役', '军衔', '勋章', '荣誉'
                ],
                'weight': 1.0
            }
        }
        
        # 初始化jieba分词
        self._init_jieba()
    
    def _init_jieba(self):
        """初始化jieba分词，添加专业词汇"""
        try:
            # 添加新词到jieba词典
            for category, data in self.category_keywords.items():
                for keyword in data['keywords']:
                    jieba.add_word(keyword)
            logger.info("jieba分词器初始化完成")
        except Exception as e:
            logger.warning(f"jieba初始化警告: {e}")
    
    def classify_news(self, title, content="", source_name=""):
        """
        智能分类新闻
        
        Args:
            title: 新闻标题
            content: 新闻内容（可选）
            source_name: 新闻源名称（可选）
            
        Returns:
            str: 分类结果
        """
        # 基于来源的预分类
        source_category = self._classify_by_source(source_name)
        if source_category:
            return source_category
        
        # 组合文本进行分析
        text = title + " " + content[:500]  # 限制内容长度
        
        # 计算各分类的匹配分数
        category_scores = {}
        
        for category, data in self.category_keywords.items():
            score = self._calculate_category_score(text, data['keywords'], data['weight'])
            if score > 0:
                category_scores[category] = score
        
        # 返回得分最高的分类
        if category_scores:
            best_category = max(category_scores, key=category_scores.get)
            max_score = category_scores[best_category]
            
            # 设置最低分数阈值
            if max_score >= 1:  # 至少匹配1个关键词即可分类
                return best_category
        
        # 默认返回综合类
        return 'general'
    
    def _classify_by_source(self, source_name):
        """基于新闻源进行预分类"""
        if not source_name:
            return None
        
        source_mapping = {
            '第一财经': 'economics',
            '财经': 'economics',
            '经济': 'economics',
            '36氪': 'technology',
            'IT之家': 'technology',
            '虎嗅网': 'technology',
            '科技': 'technology',
            '体育': 'sports',
            '娱乐': 'entertainment',
            '军事': 'military'
        }
        
        for key, category in source_mapping.items():
            if key in source_name:
                return category
        
        return None
    
    def _calculate_category_score(self, text, keywords, weight):
        """计算文本与某个分类的匹配分数"""
        score = 0
        text_lower = text.lower()
        
        # 使用jieba分词
        try:
            words = list(jieba.cut(text, cut_all=False))
            words_set = set(words)
        except:
            words_set = set(text.split())
        
        for keyword in keywords:
            keyword_lower = keyword.lower()
            
            # 1. 直接完全匹配（最高分）
            if keyword_lower in text_lower:
                score += weight * 1.0
            
            # 2. 分词精确匹配
            if keyword in words_set:
                score += weight * 0.9
            
            # 3. 部分匹配（对于长关键词）
            if len(keyword) > 2:
                for word in words_set:
                    if keyword in word or word in keyword:
                        score += weight * 0.6
                        break
            
            # 4. 模糊匹配（对于类似词汇）
            if len(keyword) > 1:
                for word in words_set:
                    if len(word) > 1:
                        # 计算相似度
                        from difflib import SequenceMatcher
                        similarity = SequenceMatcher(None, keyword, word).ratio()
                        if similarity > 0.7:  # 70%相似度
                            score += weight * 0.4
                            break
            
            # 5. 包含关键字符的单词匹配
            for word in words_set:
                if len(word) >= 2 and keyword in word:
                    score += weight * 0.3
                    break
        
        return score
    
    def get_category_name(self, category):
        """获取分类的中文名称"""
        category_names = {
            'general': '综合',
            'politics': '政治',
            'economics': '财经',
            'technology': '科技',
            'society': '社会',
            'international': '国际',
            'sports': '体育',
            'entertainment': '娱乐',
            'military': '军事'
        }
        return category_names.get(category, category)
    
    def get_all_categories(self):
        """获取所有分类及其中文名称"""
        return {
            'general': '综合',
            'politics': '政治', 
            'economics': '财经',
            'technology': '科技',
            'society': '社会',
            'international': '国际',
            'sports': '体育',
            'entertainment': '娱乐',
            'military': '军事'
        }

# 全局分类器实例
news_classifier = NewsClassifier()